// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: linchuan

#pragma once

#include <memory>
#include <string>
#include <vector>

#include "coin2/exchange/base/order/order.h"
#include "coin2/exchange/bitmex/api_util/auth_key.h"
#include "coin2/exchange/order/bitmex.pb.h"

class BitmexRateTracker;

class BitmexNativePrivateClient : public coin2::exchange::base::order::NativePrivateClient {
 public:
  using RestParams = coin2::exchange::order::BitmexRestParams;
  using OrderSpec = coin2::exchange::base::order::OrderSpec;
  using NativeClientConfig = coin2::exchange::order::OrderConnectionConfig;
  using ActionType = coin2::exchange::base::order::NativePrivateClient::ActionType;

 public:
  std::shared_ptr<AsioHttpContext> SubmitOrderExecution(const OrderExecutionProto& order);
  std::shared_ptr<AsioHttpContext> SubmitRestQuery(const RestQueryProto& query);

 public:
  explicit BitmexNativePrivateClient(
      const MarketExchangeApi& mea,
      const NativeClientConfig& config);

  std::shared_ptr<AsioHttpContext> QueryWallet();
  std::shared_ptr<AsioHttpContext> QueryMargin();
  std::shared_ptr<AsioHttpContext> QueryPosition();
  std::shared_ptr<AsioHttpContext> QueryOrders(const RestParams& params);
  std::shared_ptr<AsioHttpContext> QueryExecution(const RestParams& params);
  std::shared_ptr<AsioHttpContext> PlaceOrder(
      const RestParams& params,
      const OrderSpec& order_spec);
  std::shared_ptr<AsioHttpContext> AmendOrder(const RestParams& params);
  std::shared_ptr<AsioHttpContext> CancelSingleOrder(const RestParams& params);
  std::shared_ptr<AsioHttpContext> CancelOrders(const RestParams& params);
  std::shared_ptr<AsioHttpContext> BulkPlaceOrder(
      const std::vector<RestParams*>& vec_params,
      const OrderSpec& order_spec);
  std::shared_ptr<AsioHttpContext> BulkAmendOrder(const std::vector<RestParams*>& vec_params);

  std::shared_ptr<AsioHttpContext> PlaceOrderNorm(const OrderExecution&) override;
  std::shared_ptr<AsioHttpContext> CancelOrderNorm(const OrderExecution&) override;

  RestParams GetRestOrderParams(
      const OrderSpec& order_spec,
      int64_t proc_order_id,
      int64_t orig_proc_order_id);

  RestParams GetRestCancelParams(const IOrderContext& order_context);

  void SetMakerOrder(bool is_maker_order);

 private:
  BitmexRateTracker* local_rate_tracker_;
};
